﻿Imports System
Imports System.CodeDom
Imports System.CodeDom.Compiler
Imports System.Collections
Imports System.Collections.Generic
Imports System.ComponentModel
Imports System.ComponentModel.Design.Serialization
Imports System.Globalization
Imports System.IO
Imports System.Resources
Imports System.Security.Cryptography
Imports System.Workflow.ComponentModel
Imports System.Workflow.ComponentModel.Compiler
Imports System.Workflow.ComponentModel.Design
Imports System.Xml

Namespace System.Workflow.ComponentModel.Serialization
    Friend Class WorkflowMarkupSerializationHelpers
        ' Methods
        Friend Shared Sub FixStandardNamespacesAndRootNamespace(ByVal codeNamespaces As CodeNamespaceCollection, ByVal rootNS As String, ByVal language As SupportedLanguages)
            If (language = SupportedLanguages.VB) Then
                Dim namespace2 As CodeNamespace
                For Each namespace2 In codeNamespaces
                    If (namespace2.Name = rootNS) Then
                        namespace2.Name = String.Empty
                        namespace2.UserData.Add("TruncatedNamespace", Nothing)
                    ElseIf namespace2.Name.StartsWith((rootNS & "."), StringComparison.Ordinal) Then
                        namespace2.Name = namespace2.Name.Substring((rootNS.Length + 1))
                        namespace2.UserData.Add("TruncatedNamespace", Nothing)
                    End If
                Next
            End If
            Dim namespace3 As CodeNamespace
            For Each namespace3 In codeNamespaces
                Dim hashtable As New Hashtable
                Dim import As CodeNamespaceImport
                For Each import In namespace3.Imports
                    hashtable.Add(import.Namespace, import)
                Next
                Dim str As String
                For Each str In WorkflowMarkupSerializationHelpers.standardNamespaces
                    If Not hashtable.Contains(str) Then
                        namespace3.Imports.Add(New CodeNamespaceImport(str))
                    End If
                Next
            Next
        End Sub

        Friend Shared Function GenerateCodeFromXomlDocument(ByVal rootActivity As Activity, ByVal filePath As String, ByVal rootNamespace As String, ByVal language As SupportedLanguages, ByVal serviceProvider As IServiceProvider) As CodeNamespaceCollection
            Dim namespaces As New CodeNamespaceCollection
            Dim codeDomProvider As CodeDomProvider = CompilerHelpers.GetCodeDomProvider(language)
            Dim str As String = [TryCast](rootActivity.GetValue(WorkflowMarkupSerializer.XClassProperty),String)
            Dim declaration As CodeTypeDeclaration = Nothing
            If ((Not codeDomProvider Is Nothing) AndAlso Not String.IsNullOrEmpty(str)) Then
                Dim str2 As String
                Dim str3 As String
                Helpers.GetNamespaceAndClassName(str, str2, str3)
                If codeDomProvider.IsValidIdentifier(str3) Then
                    Dim manager As New DesignerSerializationManager(serviceProvider)
                    [Using] manager.CreateSession
                        Dim manager2 As New ActivityCodeDomSerializationManager(manager)
                        Dim serializer As TypeCodeDomSerializer = [TryCast](manager2.GetSerializer(rootActivity.GetType, GetType(TypeCodeDomSerializer)),TypeCodeDomSerializer)
                        Dim flag As Boolean = True
                        Dim list As New ArrayList
                        list.Add(rootActivity)
                        If TypeOf rootActivity Is CompositeActivity Then
                            Dim activity As Activity
                            For Each activity In Helpers.GetNestedActivities(DirectCast(rootActivity, CompositeActivity))
                                If Not Helpers.IsActivityLocked(activity) Then
                                    If codeDomProvider.IsValidIdentifier(manager2.GetName(activity)) Then
                                        list.Insert(0, activity)
                                    Else
                                        flag = False
                                        Exit For
                                    End If
                                End If
                            Next
                        End If
                        If flag Then
                            Dim site As New DummySite
                            Dim activity2 As Activity
                            For Each activity2 In list
                                activity2.Site = site
                            Next
                            rootActivity.Site = site
                            declaration = serializer.Serialize(manager2, rootActivity, list)
                            declaration.IsPartial = True
                            If ((Not filePath Is Nothing) AndAlso (filePath.Length > 0)) Then
                                Dim md As MD5 = New MD5CryptoServiceProvider
                                Dim buffer As Byte() = Nothing
                                [Using] reader As StreamReader = New StreamReader(filePath)
                                    buffer = md.ComputeHash(reader.BaseStream)
                                End [Using]
                                Dim str4 As String = String.Format(CultureInfo.InvariantCulture, "{0}{1}{2}{3}{4}{5}{6}{7}{8}{9}{10}{11}{12}{13}{14}{15}", New Object() { buffer(0).ToString("X2", CultureInfo.InvariantCulture), buffer(1).ToString("X2", CultureInfo.InvariantCulture), buffer(2).ToString("X2", CultureInfo.InvariantCulture), buffer(3).ToString("X2", CultureInfo.InvariantCulture), buffer(4).ToString("X2", CultureInfo.InvariantCulture), buffer(5).ToString("X2", CultureInfo.InvariantCulture), buffer(6).ToString("X2", CultureInfo.InvariantCulture), buffer(7).ToString("X2", CultureInfo.InvariantCulture), buffer(8).ToString("X2", CultureInfo.InvariantCulture), buffer(9).ToString("X2", CultureInfo.InvariantCulture), buffer(10).ToString("X2", CultureInfo.InvariantCulture), buffer(11).ToString("X2", CultureInfo.InvariantCulture), buffer(12).ToString("X2", CultureInfo.InvariantCulture), buffer(13).ToString("X2", CultureInfo.InvariantCulture), buffer(14).ToString("X2", CultureInfo.InvariantCulture), buffer(15).ToString("X2", CultureInfo.InvariantCulture) })
                                Dim declaration2 As New CodeAttributeDeclaration(GetType(WorkflowMarkupSourceAttribute).FullName)
                                declaration2.Arguments.Add(New CodeAttributeArgument(New CodePrimitiveExpression(filePath)))
                                declaration2.Arguments.Add(New CodeAttributeArgument(New CodePrimitiveExpression(str4)))
                                declaration.CustomAttributes.Add(declaration2)
                            End If
                            Dim namespace2 As New CodeNamespace(str2)
                            namespace2.Types.Add(declaration)
                            namespaces.Add(namespace2)
                        End If
                    End [Using]
                End If
            End If
            If (Not declaration Is Nothing) Then
                Dim queue As New Queue(New Object() { rootActivity })
                Do While (queue.Count > 0)
                    Dim activity3 As Activity = DirectCast(queue.Dequeue, Activity)
                    If Not Helpers.IsActivityLocked(activity3) Then
                        Dim queue2 As New Queue(New Object() { activity3 })
                        Do While (queue2.Count > 0)
                            Dim activity4 As Activity = DirectCast(queue2.Dequeue, Activity)
                            If TypeOf activity4 Is CompositeActivity Then
                                Dim activity5 As Activity
                                For Each activity5 In DirectCast(activity4, CompositeActivity).Activities
                                    queue2.Enqueue(activity5)
                                Next
                            End If
                            Dim members As CodeTypeMemberCollection = [TryCast](activity4.GetValue(WorkflowMarkupSerializer.XCodeProperty),CodeTypeMemberCollection)
                            If (Not members Is Nothing) Then
                                Dim member As CodeSnippetTypeMember
                                For Each member In members
                                    declaration.Members.Add(member)
                                Next
                            End If
                        Loop
                    End If
                Loop
                If (language = SupportedLanguages.CSharp) Then
                    declaration.LinePragma = New CodeLinePragma(CStr(rootActivity.GetValue(ActivityCodeDomSerializer.MarkupFileNameProperty)), Math.Max(CInt(rootActivity.GetValue(ActivityMarkupSerializer.StartLineProperty)), 1))
                End If
                Dim constructor As CodeConstructor = Nothing
                Dim method As CodeMemberMethod = Nothing
                Dim member2 As CodeTypeMember
                For Each member2 In declaration.Members
                    If ((constructor Is Nothing) AndAlso TypeOf member2 Is CodeConstructor) Then
                        constructor = [TryCast](member2,CodeConstructor)
                    End If
                    If (((method Is Nothing) AndAlso TypeOf member2 Is CodeMemberMethod) AndAlso member2.Name.Equals("InitializeComponent", StringComparison.Ordinal)) Then
                        method = [TryCast](member2,CodeMemberMethod)
                    End If
                    If ((Not constructor Is Nothing) AndAlso (Not method Is Nothing)) Then
                        Exit For
                    End If
                Next
                If (Not constructor Is Nothing) Then
                    constructor.LinePragma = New CodeLinePragma(CStr(rootActivity.GetValue(ActivityCodeDomSerializer.MarkupFileNameProperty)), Math.Max(CInt(rootActivity.GetValue(ActivityMarkupSerializer.StartLineProperty)), 1))
                End If
                If ((Not method Is Nothing) AndAlso (language = SupportedLanguages.CSharp)) Then
                    method.LinePragma = New CodeLinePragma(CStr(rootActivity.GetValue(ActivityCodeDomSerializer.MarkupFileNameProperty)), Math.Max(CInt(rootActivity.GetValue(ActivityMarkupSerializer.StartLineProperty)), 1))
                End If
            End If
            Dim list2 As List([Of] String) = [TryCast](rootActivity.GetValue(WorkflowMarkupSerializer.ClrNamespacesProperty),List([Of] String))
            If (Not list2 Is Nothing) Then
                Dim namespace3 As CodeNamespace
                For Each namespace3 In namespaces
                    Dim str5 As String
                    For Each str5 In list2
                        If Not String.IsNullOrEmpty(str5) Then
                            Dim import As New CodeNamespaceImport(str5) { _
                                .LinePragma = New CodeLinePragma(CStr(rootActivity.GetValue(ActivityCodeDomSerializer.MarkupFileNameProperty)), Math.Max(CInt(rootActivity.GetValue(ActivityMarkupSerializer.StartLineProperty)), 1)) _
                            }
                            namespace3.Imports.Add(import)
                        End If
                    Next
                Next
            End If
            Return namespaces
        End Function

        Friend Shared Function GetEventHandlerName(ByVal owner As Object, ByVal eventName As String) As String
            Dim str As String = Nothing
            Dim obj2 As DependencyObject = [TryCast](owner,DependencyObject)
            If ((Not String.IsNullOrEmpty(eventName) AndAlso (Not owner Is Nothing)) AndAlso ((Not obj2 Is Nothing) AndAlso (Not obj2.GetValue(WorkflowMarkupSerializer.EventsProperty) Is Nothing))) Then
                Dim hashtable As Hashtable = [TryCast](obj2.GetValue(WorkflowMarkupSerializer.EventsProperty),Hashtable)
                If ((Not hashtable Is Nothing) AndAlso hashtable.ContainsKey(eventName)) Then
                    str = [TryCast](hashtable.Item(eventName),String)
                End If
            End If
            Return str
        End Function

        Public Shared Function LoadXomlDocument(ByVal xomlSerializationManager As WorkflowMarkupSerializationManager, ByVal textReader As XmlReader, ByVal fileName As String) As Activity
            If (xomlSerializationManager Is Nothing) Then
                Throw New ArgumentNullException("xomlSerializationManager")
            End If
            Dim activity As Activity = Nothing
            Try 
                xomlSerializationManager.Context.Push(fileName)
                activity = [TryCast](New WorkflowMarkupSerializer().Deserialize(xomlSerializationManager, textReader),Activity)
            Finally
                xomlSerializationManager.Context.Pop
            End Try
            Return activity
        End Function

        Friend Shared Sub ProcessDefTag(ByVal serializationManager As WorkflowMarkupSerializationManager, ByVal reader As XmlReader, ByVal activity As Activity, ByVal newSegment As Boolean, ByVal fileName As String)
            Dim manager As New ResourceManager("System.Workflow.ComponentModel.StringResources", GetType(ActivityBind).Assembly)
            If (reader.NodeType = XmlNodeType.Attribute) Then
                Dim str As String
                If ((Not str = reader.LocalName Is Nothing) AndAlso (str = "Class")) Then
                    activity.SetValue(WorkflowMarkupSerializer.XClassProperty, reader.Value)
                Else
                    serializationManager.ReportError(New WorkflowMarkupSerializationException(String.Format(CultureInfo.CurrentCulture, manager.GetString("UnknownDefinitionTag"), New Object() { "x", reader.LocalName, "http://schemas.microsoft.com/winfx/2006/xaml" }), If(TypeOf reader Is IXmlLineInfo, DirectCast(reader, IXmlLineInfo).LineNumber, 1), If(TypeOf reader Is IXmlLineInfo, DirectCast(reader, IXmlLineInfo).LinePosition, 1)))
                End If
            Else
                Dim flag As Boolean = False
                Dim isEmptyElement As Boolean = reader.IsEmptyElement
                Dim depth As Integer = reader.Depth
                Do
                    Select Case reader.NodeType
                        Case XmlNodeType.Element
                            Dim localName As String = reader.LocalName
                            If (Not localName Is Nothing) Then
                                If (localName = "Code") Then
                                    If isEmptyElement Then
                                        flag = True
                                    End If
                                    Exit Select
                                End If
                                Dim flag1 As Boolean = (localName = "Constructor")
                            End If
                            serializationManager.ReportError(New WorkflowMarkupSerializationException(String.Format(CultureInfo.CurrentCulture, manager.GetString("UnknownDefinitionTag"), New Object() { "x", reader.LocalName, "http://schemas.microsoft.com/winfx/2006/xaml" }), If(TypeOf reader Is IXmlLineInfo, DirectCast(reader, IXmlLineInfo).LineNumber, 1), If(TypeOf reader Is IXmlLineInfo, DirectCast(reader, IXmlLineInfo).LinePosition, 1)))
                            Return
                        Case XmlNodeType.Text, XmlNodeType.CDATA
                            Dim num2 As Integer = If(TypeOf reader Is IXmlLineInfo, DirectCast(reader, IXmlLineInfo).LineNumber, 1)
                            Dim num3 As Integer = If(TypeOf reader Is IXmlLineInfo, DirectCast(reader, IXmlLineInfo).LinePosition, 1)
                            Dim member As New CodeSnippetTypeMember(reader.Value) { _
                                .LinePragma = New CodeLinePragma(fileName, Math.Max((num2 - 1), 1)) _
                            }
                            member.UserData.Item(UserDataKeys.CodeSegment_New) = newSegment
                            member.UserData.Item(UserDataKeys.CodeSegment_ColumnNumber) = ((num3 + reader.Name.Length) - 1)
                            Dim members As CodeTypeMemberCollection = [TryCast](activity.GetValue(WorkflowMarkupSerializer.XCodeProperty),CodeTypeMemberCollection)
                            If (members Is Nothing) Then
                                members = New CodeTypeMemberCollection
                                activity.SetValue(WorkflowMarkupSerializer.XCodeProperty, members)
                            End If
                            members.Add(member)
                            Exit Select
                        Case XmlNodeType.EndElement
                            If (reader.Depth = depth) Then
                                flag = True
                            End If
                            Exit Select
                    End Select
                Loop While (Not flag AndAlso reader.Read)
            End If
        End Sub

        Friend Shared Sub ReapplyRootNamespace(ByVal codeNamespaces As CodeNamespaceCollection, ByVal rootNS As String, ByVal language As SupportedLanguages)
            If (language = SupportedLanguages.VB) Then
                Dim namespace2 As CodeNamespace
                For Each namespace2 In codeNamespaces
                    If Not namespace2.UserData.Contains("TruncatedNamespace") Then
                        [Continue] For
                    End If
                    If ((namespace2.Name Is Nothing) OrElse (namespace2.Name.Length = 0)) Then
                        namespace2.Name = rootNS
                    ElseIf namespace2.Name.StartsWith((rootNS & "."), StringComparison.Ordinal) Then
                        namespace2.Name = (rootNS & "." & namespace2.Name)
                    End If
                    namespace2.UserData.Remove("TruncatedNamespace")
                Next
            End If
        End Sub

        Friend Shared Sub SetEventHandlerName(ByVal owner As Object, ByVal eventName As String, ByVal value As String)
            Dim obj2 As DependencyObject = [TryCast](owner,DependencyObject)
            If ((Not String.IsNullOrEmpty(eventName) AndAlso (Not owner Is Nothing)) AndAlso (Not obj2 Is Nothing)) Then
                If (obj2.GetValue(WorkflowMarkupSerializer.EventsProperty) Is Nothing) Then
                    obj2.SetValue(WorkflowMarkupSerializer.EventsProperty, New Hashtable)
                End If
                Dim hashtable As Hashtable = [TryCast](obj2.GetValue(WorkflowMarkupSerializer.EventsProperty),Hashtable)
                hashtable.Item(eventName) = value
            End If
        End Sub


        ' Fields
        Friend Shared standardNamespaces As String() = New String() { "System", "System.Collections", "System.ComponentModel", "System.ComponentModel.Design", "System.Collections.Generic", "System.Workflow.ComponentModel", "System.Workflow.Runtime", "System.Workflow.Activities" }

        ' Nested Types
        Private Class DummySite
            Implements ISite, IServiceProvider
            ' Methods
            Public Function GetService(ByVal type As Type) As Object
                Return Nothing
            End Function


            ' Properties
            Public ReadOnly Property Component As IComponent
                Get
                    Return Nothing
                End Get
            End Property

            Public ReadOnly Property Container As IContainer
                Get
                    Return Nothing
                End Get
            End Property

            Public ReadOnly Property DesignMode As Boolean
                Get
                    Return True
                End Get
            End Property

            Public Property Name As String
                Get
                    Return String.Empty
                End Get
                Set(ByVal value As String)
                End Set
            End Property

        End Class
    End Class
End Namespace

